package cn.com.cetccst.dataupload.network;


import static cn.com.cetccst.tools.device.Device.getOsv;
import static cn.com.cetccst.tools.kv.CommonKV.kvStore;

import android.content.Context;
import android.os.Build;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.google.gson.Gson;

import org.json.JSONObject;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import cn.com.cetccst.dataupload.kv.KVKeys;
import cn.com.cetccst.network.IRetrofitClient;
import cn.com.cetccst.network.RetrofitManager;
import cn.com.cetccst.network.log.IHttpLog;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import retrofit2.Call;
import retrofit2.Retrofit;

public class DataUploadHttpRequester {
    private static final String MEDIA_JSON_TYPE = "application/json;charset=UTF-8";
    private final static String PUT_CONTENT_TYPE = "application/vnd.mg.mdm.command.v1+json";
    private static final String X_TOKEN = "Authorization";
    private static final String PACKAGE_NAME = "package";
    private static final String MDM_TOKEN = "token";
    public static final String PROTO_VERSION = "5.4";
    public static final String API_VERSION_NAME = "version";
    public static final String OS_VERSION = "X-OSVersion";
    public static final String DEVICE_TYPE = "X-DType";
    public static final String BUILD_TYPE = "X-BuildType";
    private static IRetrofitClient retrofitClient;
    private static IDataUploadApiService apiService;
    private static DataUploadHttpRequester httpRequester;

    private DataUploadHttpRequester() {
    }

    public static void initialize(Context context, String baseUrl) {
        if (retrofitClient == null) {
            retrofitClient = new RetrofitManager.Builder(context, baseUrl)
                    .setLogLevel(IHttpLog.Level.BODY)
                    .addInterceptor(new Interceptor() {
                        @NonNull
                        @Override
                        public Response intercept(@NonNull Chain chain) throws IOException {
                            Request originalRequest = chain.request();
                            Request.Builder authorisedRequest = originalRequest.newBuilder();

                            //TODO token这块临时这么写，后续再优化
//                            addHeaderIfNecessary(originalRequest, authorisedRequest, X_TOKEN, kvStore != null ? "Bearer " + kvStore.decodeString(KVKeys.KEY_MDM_TOKEN) : null);
                            addHeaderIfNecessary(originalRequest, authorisedRequest, MDM_TOKEN, kvStore != null ? kvStore.decodeString(KVKeys.KEY_MDM_TOKEN) : null);
                            addHeaderIfNecessary(originalRequest, authorisedRequest, API_VERSION_NAME, PROTO_VERSION);
                            addHeaderIfNecessary(originalRequest, authorisedRequest, DEVICE_TYPE, Build.BRAND + "_" + Build.MODEL);
                            addHeaderIfNecessary(originalRequest, authorisedRequest, OS_VERSION, getOsv());
                            addHeaderIfNecessary(originalRequest, authorisedRequest, BUILD_TYPE, "du");

                            return chain.proceed(authorisedRequest.build());
                        }
                    })
                    .build();
            Retrofit retrofit = retrofitClient.getRetrofit();
            apiService = retrofit.create(IDataUploadApiService.class);
        }
    }

    public IHttpLog getHttpLogConfig() {
        return retrofitClient.getHttpLogConfig();
    }

    public OkHttpClient getOKHttpClient() {
        return retrofitClient.getOKHttpClient();
    }

    public static DataUploadHttpRequester getInstance() {
        if (httpRequester == null) {
            httpRequester = new DataUploadHttpRequester();
        }
        return httpRequester;
    }

    private static void addHeaderIfNecessary(Request orgRequest, Request.Builder newRequest, String headerName, String headerContent) {
        if (TextUtils.isEmpty(orgRequest.header(headerName)) && !TextUtils.isEmpty(headerContent)) {
            newRequest.header(headerName, headerContent);
        }
    }

    private RequestBody requestBody(String type, Object body) {
        MediaType mediaType = MediaType.parse(type);
        String bodyStr = new Gson().toJson(body);
        return RequestBody.create(bodyStr, mediaType);
    }

    public retrofit2.Response<JSONObject> requestUploadData(String name, String payload) throws IOException {
        if (apiService != null) {
            Map<String, Object> body = new HashMap<>();
            body.put("cid", UUID.randomUUID().toString());
            body.put("name", name);
            body.put("payload", payload);
            body.put("hasMoreCommand", false);
            RequestBody requestBody = requestBody(PUT_CONTENT_TYPE, body);

            Call<JSONObject> call = apiService.uploadData(requestBody);
            return call.execute();
        }
        return null;
    }

}
